package com.btl.service.ai.biz.adaptor;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.btl.boot.core.dto.response.R;
import com.btl.service.ai.auth.SecurityContextHolder;
import com.btl.service.ai.biz.dto.AnalysisCustomerQuery;
import com.btl.service.ai.biz.entity.KwDocument;
import com.btl.service.ai.biz.service.IKwDocumentService;
import com.btl.service.ai.support.query.SystemAndUserMessageTransformer;
import com.btl.service.ai.support.rag.embedding.strategy.EmbeddingModelTypeEnum;
import com.btl.service.ai.support.rag.embedding.strategy.RetrieverStrategy;
import com.btl.service.ai.support.rag.embedding.strategy.RetrieverStrategyFactory;
import com.btl.service.ai.support.rag.generation.GenerationModelEnum;
import com.btl.service.ai.support.rag.generation.assistant.GenerationAssistantFactory;
import com.btl.service.ai.support.rag.generation.assistant.GenerationAssistantStrategy;
import com.btl.service.ai.support.rag.generation.knowledge.GenerationKnowledgeFactory;
import com.btl.service.ai.support.rag.generation.knowledge.GenerationKnowledgeStrategy;
import dev.langchain4j.community.model.dashscope.QwenChatModel;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.listener.ChatModelErrorContext;
import dev.langchain4j.model.chat.listener.ChatModelListener;
import dev.langchain4j.model.chat.listener.ChatModelRequestContext;
import dev.langchain4j.model.chat.listener.ChatModelResponseContext;
import dev.langchain4j.model.openaiofficial.OpenAiOfficialChatModel;
import dev.langchain4j.rag.content.Content;
import dev.langchain4j.rag.query.Query;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.Result;
import dev.langchain4j.store.embedding.filter.Filter;
import dev.langchain4j.store.embedding.filter.comparison.IsIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author Tim
 * @since 2025-07-22
 */
@Slf4j
@Validated
@RestController
@Tag(name = "助手")
@Controller
@RequestMapping("agent")
public class AiAgentController {

    @Resource
    private IKwDocumentService iKwDocumentService;

    /**
     * 类型提问
     *
     * @param analysisCustomerQuery 查询条件
     * @return List<SplitSegmentRsp>
     */
    @PostMapping(value = "/analysis-customer")
    public R<String> analysis(@RequestBody @Valid AnalysisCustomerQuery analysisCustomerQuery) {
        String messages = analysisCustomerQuery.getMessages();
        Query query = new Query(analysisCustomerQuery.getQuestion());
        SystemAndUserMessageTransformer queryTransformer = new SystemAndUserMessageTransformer(messages);
        SystemAndUserMessageTransformer.Message transform = queryTransformer.transform(query);
        Long memoryId = analysisCustomerQuery.getMemoryId();
        GenerationAssistantStrategy generationAssistantStrategy = GenerationAssistantFactory.getStrategy(GenerationModelEnum.OPEN_AI_CHAT_MODEL);
        if (analysisCustomerQuery.getFormatJson()) {
            Result<String> generateJson = generationAssistantStrategy.generateJson(memoryId, transform.systemMessage(), transform.userMessage(), query, String.class);
            return R.ok(generateJson.content());
        }
        Result<String> generate = generationAssistantStrategy.generate(memoryId, transform.systemMessage(), transform.userMessage(), query);
        return R.ok(generate.content());
    }

    /**
     * 增强生成
     *
     * @param question 查询条件
     * @return List<SplitSegmentRsp>
     */
    @GetMapping(value = "/generate")
    public R<String> generate(@RequestParam(value = "question", required = false) @NotNull @NotBlank(message = "问题不能为空") String question,
                              @RequestParam(value = "memoryId", required = false) @NotNull(message = "记忆ID不能为空") Long memoryId) {
        Long childId = SecurityContextHolder.get()
                .getChildId();
        List<KwDocument> kwDocuments = iKwDocumentService.list(new LambdaQueryWrapper<KwDocument>().eq(KwDocument::getChildId, childId));
        GenerationKnowledgeStrategy generationStrategy = GenerationKnowledgeFactory.getStrategy(GenerationModelEnum.OPEN_AI_CHAT_MODEL);
        if (!kwDocuments.isEmpty()) {
            String collectionName = "kw_segment";
            RetrieverStrategy retrieverStrategy = RetrieverStrategyFactory.retrieverStrategy(EmbeddingModelTypeEnum.LOCAL_BGE_SMALL_ZH_V15_EMBEDDING_MODEL);
            Filter filter = new IsIn("documentId", kwDocuments.stream()
                    .map(KwDocument::getId)
                    .map(Object::toString)
                    .toList());
            List<Content> contents = retrieverStrategy.retriever(collectionName, filter, Query.from(question));
            Result<String> generate = generationStrategy.generate(memoryId, contents, new Query(question));
            return R.ok(generate.content());
        }
        Result<String> generate = generationStrategy.generate(memoryId, new ArrayList<>(), new Query(question));
        return R.ok(generate.content());
    }

    interface MathGenius {

        String ask(String question);
    }

    @Resource
    private KwKnowledgeController kwKnowledgeController;

    @GetMapping("tools")
    public R<String> tools(@RequestParam("question") String question) {
        ChatModel model = OpenAiOfficialChatModel.builder()
                .modelName(com.openai.models.ChatModel.GPT_4O_MINI)
                .baseUrl("http://139.59.125.71:3000/v1/")
                .apiKey("sk-hFTLLBHYuUuzbXOjHQmJDx1APfKrxa2ipWkk1BufXYzQQh2A")
                .build();

        ChatModel model2 = QwenChatModel.builder()
//                .apiKey("sk-b41614f0eaca4092bbe3cfb7a23e0e1f")
                .apiKey("sk-eec56f4cea7a4db2a9df954ce2097eab")
                .modelName("qwen-plus")
                .temperature(0.7F)
                .maxTokens(4096)
                .listeners(Collections.singletonList(new ChatModelListener() {
                    @Override
                    public void onRequest(ChatModelRequestContext requestContext) {
                        log.info("{}-request：{}", requestContext.modelProvider(), requestContext.chatRequest());
                    }

                    @Override
                    public void onResponse(ChatModelResponseContext responseContext) {
                        log.info("{}-response：{}", responseContext.modelProvider(), responseContext.chatResponse());
                    }

                    @Override
                    public void onError(ChatModelErrorContext errorContext) {
                        log.error("{}-error：{}", errorContext.modelProvider(), String.valueOf(errorContext.error()));
                    }
                }))
//                .defaultRequestParameters(ChatRequestParameters
//                        .builder()
//                        .responseFormat(ResponseFormat.JSON)
//                        .build())
                .build();

        AiAgentController.MathGenius mathGenius = AiServices.builder(AiAgentController.MathGenius.class)
                .chatModel(model2)
                .tools(kwKnowledgeController)
                .build();
        String answer = mathGenius.ask(question);
        System.out.println(answer);
        return R.ok("修改成功");
    }

}
